-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--          http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.
local validate = require 'mc.validate'
local utils = require 'mc.utils'
local mdb = require 'mc.mdb'

local NetworkPortRelatedItems = {}

---@class NetworkPortRelatedItems.RelatedProcessorPort
---@field ProcessorSilkText string
---@field PortId string
---@field IODieId integer
local TRelatedProcessorPort = {}
TRelatedProcessorPort.__index = TRelatedProcessorPort
TRelatedProcessorPort.group = {}

local function TRelatedProcessorPort_from_obj(obj)
    return setmetatable(obj, TRelatedProcessorPort)
end

function TRelatedProcessorPort.new(ProcessorSilkText, PortId, IODieId)
    return TRelatedProcessorPort_from_obj({ProcessorSilkText = ProcessorSilkText, PortId = PortId, IODieId = IODieId})
end
---@param obj NetworkPortRelatedItems.RelatedProcessorPort
function TRelatedProcessorPort:init_from_obj(obj)
    self.ProcessorSilkText = obj.ProcessorSilkText
    self.PortId = obj.PortId
    self.IODieId = obj.IODieId
end

function TRelatedProcessorPort:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TRelatedProcessorPort.group)
end

TRelatedProcessorPort.from_obj = TRelatedProcessorPort_from_obj

TRelatedProcessorPort.proto_property = {'ProcessorSilkText', 'PortId', 'IODieId'}

TRelatedProcessorPort.default = {'', '', 0}

TRelatedProcessorPort.struct = {
    {name = 'ProcessorSilkText', is_array = false, struct = nil}, {name = 'PortId', is_array = false, struct = nil},
    {name = 'IODieId', is_array = false, struct = nil}
}

function TRelatedProcessorPort:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'ProcessorSilkText', self.ProcessorSilkText, 'string', true, errs, need_convert)
    validate.Optional(prefix .. 'PortId', self.PortId, 'string', true, errs, need_convert)
    validate.Optional(prefix .. 'IODieId', self.IODieId, 'uint8', true, errs, need_convert)

    TRelatedProcessorPort:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TRelatedProcessorPort.proto_property, errs, need_convert)
    return self
end

function TRelatedProcessorPort:unpack(_)
    return self.ProcessorSilkText, self.PortId, self.IODieId
end

NetworkPortRelatedItems.RelatedProcessorPort = TRelatedProcessorPort

---@class NetworkPortRelatedItems.ProcessorPorts
---@field ProcessorPorts NetworkPortRelatedItems.RelatedProcessorPort[]
local TProcessorPorts = {}
TProcessorPorts.__index = TProcessorPorts
TProcessorPorts.group = {}

local function TProcessorPorts_from_obj(obj)
    obj.ProcessorPorts = utils.from_obj(NetworkPortRelatedItems.RelatedProcessorPort, obj.ProcessorPorts, true)
    return setmetatable(obj, TProcessorPorts)
end

function TProcessorPorts.new(ProcessorPorts)
    return TProcessorPorts_from_obj({ProcessorPorts = ProcessorPorts})
end
---@param obj NetworkPortRelatedItems.ProcessorPorts
function TProcessorPorts:init_from_obj(obj)
    self.ProcessorPorts = obj.ProcessorPorts
end

function TProcessorPorts:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TProcessorPorts.group)
end

TProcessorPorts.from_obj = TProcessorPorts_from_obj

TProcessorPorts.proto_property = {'ProcessorPorts'}

TProcessorPorts.default = {{}}

TProcessorPorts.struct = {
    {name = 'ProcessorPorts', is_array = true, struct = NetworkPortRelatedItems.RelatedProcessorPort.struct}
}

function TProcessorPorts:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    for _, v in pairs(self.ProcessorPorts) do
        NetworkPortRelatedItems.RelatedProcessorPort.new(v.ProcessorSilkText, v.PortId, v.IODieId):validate(prefix,
            errs, need_convert)
    end

    TProcessorPorts:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TProcessorPorts.proto_property, errs, need_convert)
    return self
end

function TProcessorPorts:unpack(raw)
    return utils.unpack(raw, self.ProcessorPorts, true)
end

NetworkPortRelatedItems.ProcessorPorts = TProcessorPorts

---@class NetworkPortRelatedItems.RelatedTransceiverLane
---@field TransceiverSilkText string
---@field TransceiverLaneId integer
local TRelatedTransceiverLane = {}
TRelatedTransceiverLane.__index = TRelatedTransceiverLane
TRelatedTransceiverLane.group = {}

local function TRelatedTransceiverLane_from_obj(obj)
    return setmetatable(obj, TRelatedTransceiverLane)
end

function TRelatedTransceiverLane.new(TransceiverSilkText, TransceiverLaneId)
    return TRelatedTransceiverLane_from_obj({
        TransceiverSilkText = TransceiverSilkText,
        TransceiverLaneId = TransceiverLaneId
    })
end
---@param obj NetworkPortRelatedItems.RelatedTransceiverLane
function TRelatedTransceiverLane:init_from_obj(obj)
    self.TransceiverSilkText = obj.TransceiverSilkText
    self.TransceiverLaneId = obj.TransceiverLaneId
end

function TRelatedTransceiverLane:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TRelatedTransceiverLane.group)
end

TRelatedTransceiverLane.from_obj = TRelatedTransceiverLane_from_obj

TRelatedTransceiverLane.proto_property = {'TransceiverSilkText', 'TransceiverLaneId'}

TRelatedTransceiverLane.default = {'', 0}

TRelatedTransceiverLane.struct = {
    {name = 'TransceiverSilkText', is_array = false, struct = nil},
    {name = 'TransceiverLaneId', is_array = false, struct = nil}
}

function TRelatedTransceiverLane:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    validate.Optional(prefix .. 'TransceiverSilkText', self.TransceiverSilkText, 'string', true, errs, need_convert)
    validate.Optional(prefix .. 'TransceiverLaneId', self.TransceiverLaneId, 'uint8', true, errs, need_convert)

    TRelatedTransceiverLane:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TRelatedTransceiverLane.proto_property, errs, need_convert)
    return self
end

function TRelatedTransceiverLane:unpack(_)
    return self.TransceiverSilkText, self.TransceiverLaneId
end

NetworkPortRelatedItems.RelatedTransceiverLane = TRelatedTransceiverLane

---@class NetworkPortRelatedItems.TransceiverLanes
---@field TransceiverLanes NetworkPortRelatedItems.RelatedTransceiverLane[]
local TTransceiverLanes = {}
TTransceiverLanes.__index = TTransceiverLanes
TTransceiverLanes.group = {}

local function TTransceiverLanes_from_obj(obj)
    obj.TransceiverLanes = utils.from_obj(NetworkPortRelatedItems.RelatedTransceiverLane, obj.TransceiverLanes, true)
    return setmetatable(obj, TTransceiverLanes)
end

function TTransceiverLanes.new(TransceiverLanes)
    return TTransceiverLanes_from_obj({TransceiverLanes = TransceiverLanes})
end
---@param obj NetworkPortRelatedItems.TransceiverLanes
function TTransceiverLanes:init_from_obj(obj)
    self.TransceiverLanes = obj.TransceiverLanes
end

function TTransceiverLanes:remove_error_props(errs, obj)
    utils.remove_obj_error_property(obj, errs, TTransceiverLanes.group)
end

TTransceiverLanes.from_obj = TTransceiverLanes_from_obj

TTransceiverLanes.proto_property = {'TransceiverLanes'}

TTransceiverLanes.default = {{}}

TTransceiverLanes.struct = {
    {name = 'TransceiverLanes', is_array = true, struct = NetworkPortRelatedItems.RelatedTransceiverLane.struct}
}

function TTransceiverLanes:validate(prefix, errs, need_convert)
    prefix = prefix or ''

    for _, v in pairs(self.TransceiverLanes) do
        NetworkPortRelatedItems.RelatedTransceiverLane.new(v.TransceiverSilkText, v.TransceiverLaneId):validate(prefix,
            errs, need_convert)
    end

    TTransceiverLanes:remove_error_props(errs, self)
    validate.CheckUnknowProperty(self, TTransceiverLanes.proto_property, errs, need_convert)
    return self
end

function TTransceiverLanes:unpack(raw)
    return utils.unpack(raw, self.TransceiverLanes, true)
end

NetworkPortRelatedItems.TransceiverLanes = TTransceiverLanes

NetworkPortRelatedItems.interface = mdb.register_interface('bmc.kepler.Systems.NetworkPort.RelatedItems', {
    TransceiverLanes = {'a(sy)', {}, true, nil},
    ProcessorPorts = {'a(ssy)', {}, true, nil}
}, {}, {})

return NetworkPortRelatedItems
